package com.zygh.lz.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zygh.lz.controller.pc.RoadRescueController;
import com.zygh.lz.dao.EquipageMapper;
import com.zygh.lz.dao.SchedulingInfoMapper;
import com.zygh.lz.dao.VehicleCoordinateMapper;
import com.zygh.lz.entity.Equipage;
import com.zygh.lz.entity.SchedulingInformation;
import com.zygh.lz.entity.VehicleCoordinate;
import com.zygh.lz.entity.vo.ScheduVehicleVO;
import com.zygh.lz.service.SchedulingInfoService;
import com.zygh.lz.util.DataTime;
import com.zygh.lz.util.DateUtils;
import com.zygh.lz.util.DistanceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: shuaiqi
 * @CreateTime: 2022-12-26  14:10
 * @Version: 1.0
 */

@Slf4j
@Service
public class SchedulingInfoServiceImpl extends ServiceImpl<SchedulingInfoMapper, SchedulingInformation> implements SchedulingInfoService {

    @Resource
    private SchedulingInfoMapper schedulingInfoMapper;
    @Resource
    private VehicleCoordinateMapper vehicleCoordinateMapper;
    @Resource
    private EquipageMapper equipageMapper;
    @Resource
    private RoadRescueController roadRescue;

    /**
     * 查询当天清障车排班信息集合
     */
    @Override
    public List<SchedulingInformation> selectAll() {
        Map<String, Date> timeMap = this.getTime();
        if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time1"), timeMap.get("time2"))) {
            List<SchedulingInformation> informations = schedulingInfoMapper.selectAll(null);
            log.debug("早高峰，当天的全部排班信息{}", informations.size());
            return informations;
        } else if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time2"), timeMap.get("time3"))) {
            List<SchedulingInformation> informations = schedulingInfoMapper.getCenterInfo(0);
            log.debug("平峰，平峰期和晚高峰的排班{}", informations.size());
            //平峰，平峰期和晚高峰的排班
            return informations;
        } else if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time3"), timeMap.get("time4"))) {
            //晚高峰的
            List<SchedulingInformation> informations = schedulingInfoMapper.selectAll(2);
            log.debug("晚高峰的{}", informations.size());
            return informations;
        }
        //其他时间
        return schedulingInfoMapper.selectAll(null);
    }

    /**
     * 获取当天排班数量，签到数量，正在清障数量和待命点数量
     */
    @Override
    public Map<String, Object> getNums() {
        Map<String, Object> map = new HashMap<>();
        //获取当天时间段内的排班信息集合
        List<SchedulingInformation> schedulingInformationList = this.getAll();
        //待命清障车集合
        //在待命点2000米范围内的，是待命中，范围外的是任务中
        List<VehicleCoordinate> waitList = new ArrayList<>();
        //签到集合
        List<String> signList = new ArrayList<>();
        for (SchedulingInformation schedulingInformation : schedulingInformationList) {
            //经度
            String longitude = schedulingInformation.getLongitude();
            //纬度
            String latitude = schedulingInformation.getLatitude();
            //根据车牌号码和车牌颜色查询车辆定位信息,实时定位信息
            VehicleCoordinate vehicleCoordinate = vehicleCoordinateMapper.getByNumber(schedulingInformation.getNumber(), schedulingInformation.getColor());
            if (vehicleCoordinate != null) {
                String lng = vehicleCoordinate.getLng();
                String lat = vehicleCoordinate.getLat();
                //签到要在待命点两千米范围内
                if (DistanceUtil.distencePC(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(latitude), Double.parseDouble(longitude), 2000)) {
                    signList.add(vehicleCoordinate.getNumber());
                }
                //在待命点2000米范围内的，是待命中，范围外的是任务中
                if (DistanceUtil.distencePC(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(latitude), Double.parseDouble(longitude), 2000)) {
                    waitList.add(vehicleCoordinate);
                } /*else {
                    underwayList.add(vehicleCoordinate);
                }*/
                //签到数量，有当天的实时坐标并且在待命点五百米内
                //if (DistanceUtil.distencePC(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(latitude), Double.parseDouble(longitude), 500)) {
                //    //每次有在五百米内的都把车牌号添加集合中
                //    signList.add(vehicleCoordinate.getNumber());
                //}
            }
        }
        //待命清障车数量
        map.put("wait", waitList.size());
        //正在清障数量
        map.put("underway", this.getUnderway().size());
        //排班数量
        map.put("scheduling", this.selectAll().size());
        //累计在线数量
        int accumulative = 0;
        Map<String, Date> timeMap = this.getTime();
        if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time1"), timeMap.get("time2"))) {
            List<SchedulingInformation> list = schedulingInfoMapper.selectAll(0);
            for (SchedulingInformation schedulingInformation : list) {
                //根据车牌号和车牌颜色查有今天坐标的
                VehicleCoordinate vehicleCoordinate = vehicleCoordinateMapper.getByNumber(schedulingInformation.getNumber(), schedulingInformation.getColor());
                if (vehicleCoordinate != null) {
                    accumulative++;
                }
            }
        } else if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time2"), timeMap.get("time3"))) {
            List<SchedulingInformation> list = schedulingInfoMapper.selectAll(1);
            for (SchedulingInformation schedulingInformation : list) {
                VehicleCoordinate vehicleCoordinate = vehicleCoordinateMapper.getByNumber(schedulingInformation.getNumber(), schedulingInformation.getColor());
                if (vehicleCoordinate != null) {
                    accumulative++;
                }
            }
            List<SchedulingInformation> list1 = schedulingInfoMapper.selectAll(0);
            for (SchedulingInformation schedulingInformation : list1) {
                VehicleCoordinate vehicleCoordinate = vehicleCoordinateMapper.getByNumber(schedulingInformation.getNumber(), schedulingInformation.getColor());
                if (vehicleCoordinate != null) {
                    accumulative++;
                }
            }
        } else {
            //查询当天排班的全部信息
            List<SchedulingInformation> selectAll = schedulingInfoMapper.selectAll(null);
            for (SchedulingInformation schedulingInformation : selectAll) {
                //根据车牌号和车牌颜色查有今天坐标的
                VehicleCoordinate vehicleCoordinate = vehicleCoordinateMapper.getByNumber(schedulingInformation.getNumber(), schedulingInformation.getColor());
                if (vehicleCoordinate != null) {
                    accumulative++;
                }
            }
        }
        map.put("accumulative", accumulative);
        //签到数量，待命点2公里内
        //去重
        HashSet set = new HashSet(signList);
        signList.clear();
        signList.addAll(set);
        map.put("sign", signList.size());
        //获取当天的待命点数量
        Integer waitPointCount = schedulingInfoMapper.getWaitPointCount();
        map.put("waitPointCount", waitPointCount);
        //车辆总数
        Integer carCount = roadRescue.getCarCount();
        if (carCount == null) {
            carCount = 55;
        }
        //排班车辆总数
        Integer schedulingCarCount = schedulingInfoMapper.getSchedulingCarCount();
        //待命车辆数量,车辆总数-排班车辆数
        map.put("waitPointCar", carCount);
        return map;
    }

    /**
     * 获取清障车各时段的排班信息
     */
    public List<SchedulingInformation> getAll() {
        Map<String, Date> timeMap = this.getTime();
        if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time1"), timeMap.get("time2"))) {
            //早高峰，当天的全部排班信息
            return schedulingInfoMapper.selectAll(0);
        } else if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time2"), timeMap.get("time3"))) {
            //平峰，平峰期和晚高峰的排班
            return schedulingInfoMapper.selectAll(1);
        } else if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time3"), timeMap.get("time4"))) {
            //晚高峰的
            return schedulingInfoMapper.selectAll(2);
        }
        //其他时间
        return schedulingInfoMapper.selectAll(null);
    }

    /**
     * 获取清障车实时在线信息
     */
    @Override
    public List<ScheduVehicleVO> getInfo() {
        //获取当天的排班信息集合
        List<SchedulingInformation> schedulingInformationList = schedulingInfoMapper.selectAll(null);
        //清障车定位信息
        List<ScheduVehicleVO> scheduVehicleVOList = new ArrayList<>();
        for (SchedulingInformation schedulingInformation : schedulingInformationList) {
            //经度
            String longitude = schedulingInformation.getLongitude();
            //纬度
            String latitude = schedulingInformation.getLatitude();
            //根据车牌号码和车牌颜色查询车辆定位信息,实时定位信息
            ScheduVehicleVO scheduVehicleVO = vehicleCoordinateMapper.getInfo(schedulingInformation.getNumber(), schedulingInformation.getColor());
            if (scheduVehicleVO != null) {
                String lat = scheduVehicleVO.getLat();
                String lng = scheduVehicleVO.getLng();
                //在待命点500米范围内的，是待命中，范围外的是任务中
                if (DistanceUtil.distencePC(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(latitude), Double.parseDouble(longitude), 500)) {
                    //待命清障车
                    scheduVehicleVO.setState(0);
                    scheduVehicleVOList.add(scheduVehicleVO);
                } else {
                    //作业清障车
                    scheduVehicleVO.setState(1);
                    scheduVehicleVOList.add(scheduVehicleVO);
                }
            }
        }
        //去重，一辆车在多个时段都有排班，展示一个定位
        HashSet<ScheduVehicleVO> set = new HashSet(scheduVehicleVOList);
        scheduVehicleVOList.clear();
        scheduVehicleVOList.addAll(set);
        return scheduVehicleVOList;
    }

    @Override
    public PageInfo<SchedulingInformation> getByTimeSection(int pageNum, int pageSize, Integer timeBucket, String companyName) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(schedulingInfoMapper.getByTimeSection(timeBucket, companyName));
    }

    /**
     * 根据待命点和时段查询清障车详情
     *
     * @param pointName  待命点
     * @param timeBucket 时段
     * @return
     */
    @Override
    public List<SchedulingInformation> getDetails(String pointName, Integer timeBucket) {
        List<SchedulingInformation> detailsList = schedulingInfoMapper.getDetails(pointName, timeBucket);
        //早高峰
        List<SchedulingInformation> morningList = new ArrayList<>();
        //平峰期
        List<SchedulingInformation> pacificList = new ArrayList<>();
        ;
        //晚高峰
        List<SchedulingInformation> nightList = new ArrayList<>();
        for (SchedulingInformation schedulingInformation : detailsList) {
            if (timeBucket == null) {
                //全天数量
                schedulingInformation.setCounts(detailsList.size());
            }
            if (timeBucket != null && timeBucket == 0) {
                morningList.add(schedulingInformation);
                //早高峰的数量
                schedulingInformation.setCounts(morningList.size());
            } else if (timeBucket != null && timeBucket == 1) {
                pacificList.add(schedulingInformation);
                //平峰期的数量
                schedulingInformation.setCounts(pacificList.size());
            } else if (timeBucket != null && timeBucket == 2) {
                nightList.add(schedulingInformation);
                //晚高峰的数量
                schedulingInformation.setCounts(nightList.size());
            }
        }
        return detailsList;
    }

    /**
     * 每天早上五点定时删除七天前清障车排班的数据
     */
    @Override
    public void deleteSchedulingInfo() {
        //上周的开始时间
        String startYesterday = DateUtils.getBeginDayOfLastWeek();
        //上周的结束时间
        String endYesterday = DateUtils.getEndDayOfLastWeek();
        schedulingInfoMapper.deleteSchedulingInfo(startYesterday);
    }

    /**
     * 根据id查询清障车或者警车信息
     *
     * @param id id
     * @return
     */
    @Override
    public Map<String, Object> getByIdAndNumber(Integer id) {
        SchedulingInformation schedulingInformation = schedulingInfoMapper.getByIdAndNumber(id);
        if (schedulingInformation != null) {
            Map<String, Object> wreckerMap = new HashMap<>();
            //经度
            String longitude = schedulingInformation.getLongitude();
            //纬度
            String latitude = schedulingInformation.getLatitude();
            //根据车牌号码和车牌颜色查询车辆定位信息,实时定位信息
            ScheduVehicleVO scheduVehicleVO = vehicleCoordinateMapper.getInfo(schedulingInformation.getNumber(), schedulingInformation.getColor());
            if (scheduVehicleVO != null) {
                String lat = scheduVehicleVO.getLat();
                String lng = scheduVehicleVO.getLng();
                //在待命点500米范围内的，是待命中，范围外的是任务中
                if (DistanceUtil.distencePC(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(latitude), Double.parseDouble(longitude), 500)) {
                    //待命清障车
                    scheduVehicleVO.setState(0);
                } else {
                    //作业清障车
                    scheduVehicleVO.setState(1);
                }
                wreckerMap.put("id", scheduVehicleVO.getId());
                wreckerMap.put("driver", scheduVehicleVO.getDriver());
                wreckerMap.put("number", scheduVehicleVO.getNumber());
                wreckerMap.put("driverPhone", scheduVehicleVO.getDriverPhone());
                wreckerMap.put("lng", scheduVehicleVO.getLng());
                wreckerMap.put("lat", scheduVehicleVO.getLat());
                wreckerMap.put("state", scheduVehicleVO.getState());
                //返回清障车数据
                return wreckerMap;
            }
        }
        //在线的警车
        Map<String, Object> onLineMap = equipageMapper.findOnLine(id);
        if (ObjectUtil.isNotEmpty(onLineMap)) {
            onLineMap.put("notOnLine", 0);
            return onLineMap;
        }
        //不在线的警车
        Map<String, Object> notOnLineMap = equipageMapper.findNotOnLine(id);
        if (ObjectUtil.isNotEmpty(notOnLineMap)) {
            notOnLineMap.put("notOnLine", 1);
            return notOnLineMap;
        }
        return null;
    }

    @Override
    public List<Map<String, Object>> getByDriver(String driver) {
        //清障车信息
        return schedulingInfoMapper.findByNumber(driver);
    }


    /**
     * 正在清障数量
     */
    public List<Integer> getUnderway() {
        Map<String, Date> timeMap = this.getTime();
        //获取当天的排班信息集合
        List<SchedulingInformation> schedulingInformationList = schedulingInfoMapper.selectAll(null);
        //正在清障集合
        List<Integer> numList = new ArrayList<>();
        for (SchedulingInformation schedulingInformation : schedulingInformationList) {
            //经度
            String longitude = schedulingInformation.getLongitude();
            //纬度
            String latitude = schedulingInformation.getLatitude();
            //根据车牌号码和车牌颜色查询车辆定位信息,实时定位信息
            VehicleCoordinate vehicleCoordinate = vehicleCoordinateMapper.getByNumber(schedulingInformation.getNumber(), schedulingInformation.getColor());
            if (vehicleCoordinate != null) {
                String lat = vehicleCoordinate.getLat();
                String lng = vehicleCoordinate.getLng();
                //排班时间在早高峰
                if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time1"), timeMap.get("time2")) && schedulingInformation.getTimeBucket() == 0) {
                    //在待命点2000米范围内的，是待命中，范围外的是任务中
                    if (!DistanceUtil.distencePC(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(latitude), Double.parseDouble(longitude), 2000)) {
                        //作业清障车
                        numList.add(vehicleCoordinate.getId());
                    }
                    //排班时间在平峰期
                } else if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time2"), timeMap.get("time3")) && schedulingInformation.getTimeBucket() == 1) {
                    if (!DistanceUtil.distencePC(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(latitude), Double.parseDouble(longitude), 2000)) {
                        //作业清障车
                        numList.add(vehicleCoordinate.getId());
                    }
                    //排班时间在晚高峰
                } else if (com.zygh.lz.util.DateUtil.belongCalendar(timeMap.get("now"), timeMap.get("time3"), timeMap.get("time4")) && schedulingInformation.getTimeBucket() == 2) {
                    if (!DistanceUtil.distencePC(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(latitude), Double.parseDouble(longitude), 2000)) {
                        //作业清障车
                        numList.add(vehicleCoordinate.getId());
                    }
                }
            }
        }
        return numList;
    }

    /**
     * 获取时间段
     */
    public Map<String, Date> getTime() {
        Map<String, Date> map = new HashMap<>();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 设置日期格式
        Date now = null;
        Date time1 = null;
        Date time2 = null;
        Date time3 = null;
        Date time4 = null;
        try {
            String today = DateUtil.today();
            now = df.parse(df.format(new Date()));
            time1 = df.parse(today + " 07:00:00");
            time2 = df.parse(today + " 09:00:00");
            time3 = df.parse(today + " 17:00:00");
            time4 = df.parse(today + " 19:00:00");
            map.put("now", now);
            map.put("time1", time1);
            map.put("time2", time2);
            map.put("time3", time3);
            map.put("time4", time4);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

}
